#include <curses.h>
#include <stdlib.h>
#include <time.h>


#define Y_ 24
#define X_ 24
#define ENT_ 20

typedef struct {
    int y,x,hp;
}ent;

char map[Y_][X_];
ent ent_l[ENT_], *ent_m[Y_][X_];


init_map() {
    for (int y=0;y<Y_;y++)
        for (int x=0;x<X_;x++) {
            map[y][x]=' ';
            if (0==y||0==x||Y_-1==y||X_-1==x)
                map[y][x]='#';
        }
}

init_ent() {
    for (int e=0;e<ENT_;e++) {
        ent *ce=&ent_l[e];
        ce->hp=3;
        while (' '!=map[ce->y=rand()%Y_][ce->x=rand()%X_] || NULL!=ent_m[ce->y][ce->x])
            ;
        ent_m[ce->y][ce->x]=ce;
    }
}

wall(y,x) {
    return '#'==map[y][x];
}

entity(y,x) {
    return NULL!=ent_m[y][x];
}

move_to(int *y,int *x,int dy,int dx) {
    if (!wall((*y)+dy,(*x)+dx)) {
        if (entity((*y)+dy,(*x)+dx)) {
            if (0<--(ent_m[(*y)+dy][(*x)+dx]->hp)) {
                dy=0;
                dx=0;
            } else {
                ent_m[(*y)+dy][(*x)+dx]=NULL;
            }
        }
        (*y)+=dy;
        (*x)+=dx;
    }
}

main() {
    keypad(initscr(),1);
    curs_set(0);
    srand(time(0));
    init_map();
    init_ent();
    ent *pl=&ent_l[0];
    int c;
    while (27!=(c=getch())) {
        for (int yy=0;yy<Y_;yy++)
            for (int xx=0;xx<X_;xx++)
                mvaddch(yy,xx,map[yy][xx]);
        if (KEY_UP==c)
            move_to(&(pl->y),&(pl->x),-1,0);
        if (KEY_DOWN==c)
            move_to(&(pl->y),&(pl->x),1,0);
        if (KEY_LEFT==c)
            move_to(&(pl->y),&(pl->x),0,-1);
        if (KEY_RIGHT==c)
            move_to(&(pl->y),&(pl->x),0,1);
        for (int e=0;e<ENT_;e++)
            if (ent_l[e].hp>0)
                mvaddch(ent_l[e].y,ent_l[e].x,0==e?'@':'M');
    }
    endwin();
}
